#pragma once
#include "EventHandler.hpp"
#include <unordered_map>
#include <sys/epoll.h>
#include "Common.hpp"

class Epoll
{
public:
    Epoll()
    {
        _epfd = epoll_create1(0);
        if(_epfd == -1)
        {
            LOG(LogLevel::FATAL) << "EpollReactor: epoll实例创建失败! ";
            exit(EPCREATE_ERROR);
        }
    }
    // 添加事件处理器
    bool AddEventHandler(const std::shared_ptr<EventHandler>& event_handler, uint32_t events)
    {
        int fd = event_handler->Fd();
        if(_event_handlers.count(fd))
        {
            LOG(LogLevel::WARNING) << "EpollReactor::AddEventHandler: fd[" << fd << "]已存在! ";
            return false;
        }
        epoll_event epev;
        epev.data.fd = fd;
        epev.events = events;
        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, fd, &epev);
        if(n == -1)
        {
            LOG(LogLevel::ERROR) << "EpollReactor::AddEventHandler: fd[" << fd << "]添加失败! " << strerror(errno);
            return false;
        }
        _event_handlers[fd] = event_handler;
        return true;
    }
    // 删除事件处理器
    bool DelEventHandler(const std::shared_ptr<EventHandler>& event_handler)
    {
        int fd = event_handler->Fd();
        if(!_event_handlers.count(fd))
        {
            LOG(LogLevel::WARNING) << "EpollReactor::DelEventHandler: fd[" << fd << "]不存在! ";
            return false;
        }
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, fd, nullptr);
        if(n == -1)
        {
            LOG(LogLevel::ERROR) << "EpollReactor::DelEventHandler: fd[" << fd << "]删除失败! " << strerror(errno);
            return false;
        }
        _event_handlers.erase(fd);
        return true;
    }
    // 修改事件处理器
    bool ModEventHandler(const std::shared_ptr<EventHandler>& event_handler, uint32_t events)
    {
        int fd = event_handler->Fd();
        if(!_event_handlers.count(fd))
        {
            LOG(LogLevel::WARNING) << "EpollReactor::ModEventHandler: fd[" << fd << "]不存在! ";
            return false;
        }
        epoll_event epev;
        epev.data.fd = fd;
        epev.events = events;
        int n = epoll_ctl(_epfd, EPOLL_CTL_MOD, fd, &epev);
        if(n == -1)
        {
            LOG(LogLevel::ERROR) << "EpollReactor::ModEventHandler: fd[" << fd << "]修改失败! " << strerror(errno);
            return false;
        }
        return true;
    }
    // 等待事件触发
    int Wait(std::vector<epoll_event>& ready, int timeout)
    {
        int n = epoll_wait(_epfd, ready.data(), ready.size(), timeout);
        if(n == 0)
        {
            LOG(LogLevel::WARNING) << "EpollReactor::Wait: 超时... ";
        }
        else if(n == -1)
        {
            LOG(LogLevel::ERROR) << "EpollReactor::Wait: 出错! ";
        }
        return n;
    }
    // 获取对应文件描述符的事件处理器
    std::shared_ptr<EventHandler> GetHandler(int fd)
    {
        if(!_event_handlers.count(fd))
            return nullptr;
        return _event_handlers[fd];
    }
    size_t Size()
    {
        return _event_handlers.size();
    }
    ~Epoll() {}
private:
    int _epfd;
    std::unordered_map<int, std::shared_ptr<EventHandler>> _event_handlers;
};